const canvas = document.querySelector("#canvas") as HTMLCanvasElement;
const ctx = canvas.getContext("2d") as CanvasRenderingContext2D;

canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

const arr: Line[] = [];

let xZou = 0;
let yZou = 0;
function random(min: number, max: number) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

class Line {
  x: number = Math.floor(Math.random() * canvas.width);
  y: number = Math.floor(Math.random() * canvas.height);
  dx: number = random(-2, 2); //确保能够正负方向运动
  dy: number = random(-2, 2); //确保能够正负方向运动
  r: number;
  color: string;
  i: number;
  constructor(color: string, r: number) {
    this.color = color;
    this.r = r;
    arr.push(this);
    this.i = arr.length - 1;
    this.isZero();
  }

  isZero() {
    this.dx = random(-2, 2);
    this.dy = random(-2, 2);
    // 有时球沿着 X 或 Y 轴单一方向运动，可能是因为 dx 或 dy 的初始值为零，导致球只在一个轴上运动。为了避免这种情况，可以确保 dx 和 dy 的值不为零。可以使用一个简单的检查和重新分配逻辑来保证这两个值不会是零。
    if (this.dx === 0) {
      this.dx = random(1, 2) * (Math.random() > 0.5 ? 1 : -1);
    }
    if (this.dy === 0) {
      this.dy = random(1, 2) * (Math.random() > 0.5 ? 1 : -1);
    }
  }
  draw() {
    ctx.beginPath();
    ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2);
    ctx.globalAlpha = 1;
    ctx.fillStyle = this.color;
    ctx.fill();
    // 画线
    for (let index = this.i; index < arr.length; index++) {
      if (
        Math.abs(this.x - arr[index].x) < 150 &&
        Math.abs(this.y - arr[index].y) < 150
      ) {
        ctx.beginPath();
        ctx.moveTo(this.x, this.y);
        ctx.lineWidth = 2;
        // 鼠标移动连线
        if (Math.abs(this.x - xZou) < 150 && Math.abs(this.y - yZou) < 150) {
            ctx.lineTo(xZou, yZou);
        }
        ctx.lineTo(arr[index].x, arr[index].y);

        let tm =
          Math.sqrt(
            Math.pow(this.x - arr[index].x, 2) +
              Math.pow(this.y - arr[index].y, 2)
          ) / 212;
          // 线条越远越淡
        ctx.strokeStyle = `rgba(7, 156, 255,${1 - tm})`;
        ctx.closePath();
        ctx.stroke();
      }
    }
  }

  move() {
    this.x += this.dx;
    this.y += this.dy;
    if (this.y - this.r < 0 || this.y + this.r > canvas.height) {
      this.dy *= -1;
    }
    if (this.x - this.r < 0 || this.x + this.r > canvas.width) {
      this.dx *= -1;
    }

  }
}

for (let index = 0; index < 100; index++) {
  new Line("blue", 15);
}

// 让小球跟随鼠标移动
function updates() {
    for (let i = 0; i < arr.length; i++) {
        /* 更新球的坐标，鼠标坐标与球之间只有x轴与y轴都只相差150内的球才会跟着鼠标走 */
        if (Math.abs(arr[i].x - xZou) < 150 && Math.abs(arr[i].y - yZou) < 150 ) {
            /* 离鼠标越近走越慢 */
            arr[i].x += -(arr[i].x - xZou) / (10 * Math.random() + 20);
            arr[i].y += -(arr[i].y - yZou) / (10 * Math.random() + 20);
        }
        /* 否则球走的距离与方向为原数组里存放的 */
        else {
            arr[i].x += arr[i].dx;
            arr[i].y += arr[i].dy;
        }
        /* 当球边碰到窗口边时把原来走的距离设置为负数，这样小球会碰撞效果 */
        if (arr[i].x <= arr[i].r || arr[i].x >= (canvas.width - arr[i].r)) {
            arr[i].dx = -arr[i].dx;
        }
        if (arr[i].y <= arr[i].r || arr[i].y >= (canvas.height - arr[i].r)) {
            arr[i].dy = -arr[i].dy;
        }
    }
}
function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (const key in arr) {
    arr[key].draw();
    arr[key].move();

  }
  updates()
  requestAnimationFrame(animate);
}

canvas.addEventListener("mousemove", function (e) {
  xZou = e.offsetX;
  yZou = e.offsetY;
  console.log(xZou,yZou);
});
canvas.addEventListener("mouseout", function (e) {
  xZou = 0
  yZou = 0;
  console.log(xZou,yZou);
});

animate();
